package com.hejing.反射的应用;

import org.junit.Test;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

/**
 * ClassName: OtherTest
 * Package: com.hejing.反射的应用
 * Description:
 *
 * @Author: HeJing
 * @Create: 2023-06-04 19:28
 * @Version: 1.0
 */
public class OtherTest {

    // 获取运行时类的内部结构: 父类、接口、包、带泛型的父类、父类的泛型
    // 1、获取运行时类的父类。
    @Test
    public void test01() throws ClassNotFoundException {
        Class clazz = Class.forName("com.hejing.反射的应用.Person");
        Class superClass = clazz.getSuperclass();
        System.out.println(superClass);
    }

    // 2、获取运行时类实现的接口
    @Test
    public void test02() throws ClassNotFoundException {
        Class clazz = Class.forName("com.hejing.反射的应用.Person");

        Class[] interfaces = clazz.getInterfaces();
        for(Class c: interfaces) {
            System.out.println(c);
        }
    }

    // 3、获取运行时类所在的包
    @Test
    public void test03() throws ClassNotFoundException {
        Class clazz = Class.forName("com.hejing.反射的应用.Person");
        Package pack = clazz.getPackage();
        System.out.println(pack);
    }

    // 4、获取运行时类的带泛型的父类。
    @Test
    public void test04() throws ClassNotFoundException {
        Class clazz = Class.forName("com.hejing.反射的应用.Person");
        Type superClass = clazz.getGenericSuperclass();
        System.out.println(superClass);
    }

    // 5、获取运行时类的父类的泛型。

    /**
     * 平时写的代码:
     *      类型1: 业务逻辑代码 (多关注)
     *      类型2: 算法逻辑代码 (多积累)
     * @throws ClassNotFoundException
     */
    @Test
    public void test05() throws ClassNotFoundException {
        Class clazz = Class.forName("com.hejing.反射的应用.Person");

        // 获取带泛型的父类(Type是一个接口，Class实现了此接口)
        Type superClass = clazz.getGenericSuperclass();  // 得到带泛型的父类。
        // 如果父类是带泛型的，则可以强转为ParameterizedType
        ParameterizedType paramType = (ParameterizedType) superClass;
        // 调用getActualTypeArguments()获取泛型的参数，结果是一个数组，因为可能由多个泛型参数。
        Type[] arguments = paramType.getActualTypeArguments();  // 泛型参数构成的数组。
        System.out.println(arguments[0]);  // class java.lang.String
        // 获取泛型参数的名称。
        System.out.println(((Class)arguments[0]).getName());  // java.lang.String
    }
}

























